winsafe\gui\windows/
raw_opts.rs

1use crate::co;
2use crate::decl::*;
3use crate::guard::*;
4use crate::gui::*;
5use crate::prelude::*;
6
7/// Options to create a [`WindowControl`](crate::gui::WindowControl)
8/// programmatically with [`WindowControl::new`](crate::gui::WindowControl::new).
9pub struct WindowControlOpts {
10	/// Window class name to be
11	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
12	///
13	/// Defaults to an auto-generated string.
14	pub class_name: String,
15	/// Window class styles to be
16	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
17	///
18	/// Defaults to `co::CS::DBLCLKS`.
19	pub class_style: co::CS,
20	/// Window main icon to be
21	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
22	///
23	/// Defaults to `gui::Icon::None`.
24	pub class_icon: Icon,
25	/// Window cursor to be
26	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
27	///
28	/// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
29	pub class_cursor: Cursor,
30	/// Window background brush to be
31	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
32	///
33	/// Defaults to `gui::Brush::Color(co::COLOR::WINDOW)`.
34	pub class_bg_brush: Brush,
35
36	/// Left and top position coordinates of control within parent's client
37	/// area, to be
38	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
39	///
40	/// Defaults to `gui::dpi(0, 0)`.
41	pub position: (i32, i32),
42	/// Width and height of window to be
43	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
44	///
45	/// Defaults to `gui::dpi(100, 80)`.
46	pub size: (i32, i32),
47	/// Window styles to be
48	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
49	///
50	/// Defaults to `WS::CHILD | WS::TABSTOP | WS::GROUP | WS::VISIBLE | WS::CLIPCHILDREN | WS::CLIPSIBLINGS`.
51	pub style: co::WS,
52	/// Extended window styles to be
53	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
54	///
55	/// Defaults to `WS_EX::LEFT`.
56	///
57	/// Suggestion:
58	/// * `WS_EX::CLIENTEDGE` to have a border.
59	pub ex_style: co::WS_EX,
60
61	/// The control ID.
62	///
63	/// Defaults to an auto-generated ID.
64	pub ctrl_id: u16,
65	/// Horizontal and vertical behavior of the control when the parent window
66	/// is resized.
67	///
68	/// Defaults to `(gui::Horz::None, gui::Vert::None)`.
69	pub resize_behavior: (Horz, Vert),
70}
71
72impl Default for WindowControlOpts {
73	fn default() -> Self {
74		Self {
75			class_name: "".to_owned(),
76			class_style: co::CS::DBLCLKS,
77			class_icon: Icon::None,
78			class_cursor: Cursor::Idc(co::IDC::ARROW),
79			class_bg_brush: Brush::Color(co::COLOR::WINDOW),
80			position: dpi(0, 0),
81			size: dpi(100, 80),
82			style: co::WS::CHILD
83				| co::WS::TABSTOP
84				| co::WS::GROUP
85				| co::WS::VISIBLE
86				| co::WS::CLIPCHILDREN
87				| co::WS::CLIPSIBLINGS,
88			ex_style: co::WS_EX::LEFT,
89			ctrl_id: 0,
90			resize_behavior: (Horz::None, Vert::None),
91		}
92	}
93}
94
95/// Options to create a [`WindowMain`](crate::gui::WindowMain) programmatically
96/// with [`WindowMain::new`](crate::gui::WindowMain::new).
97pub struct WindowMainOpts {
98	/// Window class name to be
99	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
100	///
101	/// Defaults to an auto-generated string.
102	pub class_name: String,
103	/// Window class styles to be
104	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
105	///
106	/// Defaults to `co::CS::DBLCLKS`.
107	pub class_style: co::CS,
108	/// Window main icon to be
109	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
110	///
111	/// Defaults to `gui::Icon::None`.
112	pub class_icon: Icon,
113	/// Window cursor to be
114	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
115	///
116	/// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
117	pub class_cursor: Cursor,
118	/// Window background brush to be
119	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
120	///
121	/// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
122	pub class_bg_brush: Brush,
123
124	/// Window title to be
125	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
126	///
127	/// Defaults to empty string.
128	pub title: String,
129	/// Width and height of window client area, in pixels, to be
130	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
131	/// Does not include title bar or borders.
132	///
133	/// Defaults to `gui::dpi(600, 400)`.
134	pub size: (i32, i32),
135	/// Window styles to be
136	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
137	///
138	/// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
139	///
140	/// Suggestions:
141	/// * `WS::SIZEBOX` to make the window resizable;
142	/// * `WS::MINIMIZEBOX` to have a minimize button;
143	/// * `WS::MAXIMIZEBOX` to have a maximize button.
144	pub style: co::WS,
145	/// Extended window styles to be
146	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
147	///
148	/// Defaults to `WS_EX::LEFT`.
149	pub ex_style: co::WS_EX,
150	/// Main menu of the window to be
151	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
152	///
153	/// This menu is **not** shared: the window will own it, and destroy it when
154	/// the window is destroyed.
155	///
156	/// Defaults to none.
157	pub menu: HMENU,
158	/// Main accelerator table of the window to be
159	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
160	/// Use
161	/// [`HACCEL::CreateAcceleratorTable`](crate::HACCEL::CreateAcceleratorTable)
162	/// to create one.
163	///
164	/// Defaults to `None`.
165	pub accel_table: Option<DestroyAcceleratorTableGuard>,
166	/// In most applications, the window loop calls
167	/// [`IsDialogMessage`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isdialogmessagew)
168	/// so child control messages will properly work. However, this has the side
169	/// effect of inhibiting
170	/// [`WM_CHAR`](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-char)
171	/// messages from being sent to the window procedure. So, applications which
172	/// do not have child controls and deal directly with character processing –
173	/// like text editors – will never be able to receive `WM_CHAR`.
174	///
175	/// This flag, when `true`, will enable the normal `IsDialogMessage` call in
176	/// the window loop. When `false`, the call will be suppressed.
177	///
178	/// Defaults to `true`.
179	pub process_dlg_msgs: bool,
180}
181
182impl Default for WindowMainOpts {
183	fn default() -> Self {
184		Self {
185			class_name: "".to_owned(),
186			class_style: co::CS::DBLCLKS,
187			class_icon: Icon::None,
188			class_cursor: Cursor::Idc(co::IDC::ARROW),
189			class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
190			title: "".to_owned(),
191			size: dpi(600, 400),
192			style: co::WS::CAPTION
193				| co::WS::SYSMENU
194				| co::WS::CLIPCHILDREN
195				| co::WS::BORDER
196				| co::WS::VISIBLE,
197			ex_style: co::WS_EX::LEFT,
198			menu: HMENU::NULL,
199			accel_table: None,
200			process_dlg_msgs: true,
201		}
202	}
203}
204
205/// Options to create a [`WindowModal`](crate::gui::WindowModal)
206/// programmatically with [`WindowModal::new`](crate::gui::WindowModal::new).
207pub struct WindowModalOpts {
208	/// Window class name to be
209	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
210	///
211	/// Defaults to an auto-generated string.
212	pub class_name: String,
213	/// Window class styles to be
214	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
215	///
216	/// Defaults to `co::CS::DBLCLKS`.
217	pub class_style: co::CS,
218	/// Window main icon to be
219	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
220	///
221	/// Defaults to `gui::Icon::None`.
222	pub class_icon: Icon,
223	/// Window cursor to be
224	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
225	///
226	/// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
227	pub class_cursor: Cursor,
228	/// Window background brush to be
229	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
230	///
231	/// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
232	pub class_bg_brush: Brush,
233
234	/// Window title to be
235	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
236	///
237	/// Defaults to empty string.
238	pub title: String,
239	/// Width and height of window client area, in pixels, to be
240	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
241	/// Does not include title bar or borders.
242	///
243	/// Defaults to `gui::dpi(500, 400)`.
244	pub size: (i32, i32),
245	/// Window styles to be
246	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
247	///
248	/// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
249	///
250	/// Suggestions:
251	/// * `WS::SIZEBOX` to make the window resizable;
252	/// * `WS::MAXIMIZEBOX` to have a maximize button.
253	pub style: co::WS,
254	/// Extended window styles to be
255	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
256	///
257	/// Defaults to `WS_EX::LEFT | WS_EX::DLGMODALFRAME`.
258	pub ex_style: co::WS_EX,
259	/// In most applications, the window loop calls
260	/// [`IsDialogMessage`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isdialogmessagew)
261	/// so child control messages will properly work. However, this has the side
262	/// effect of inhibiting
263	/// [`WM_CHAR`](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-char)
264	/// messages from being sent to the window procedure. So, applications which
265	/// do not have child controls and deal directly with character processing –
266	/// like text editors – will never be able to receive `WM_CHAR`.
267	///
268	/// This flag, when `true`, will enable the normal `IsDialogMessage` call in
269	/// the window loop. When `false`, the call will be suppressed.
270	///
271	/// Defaults to `true`.
272	pub process_dlg_msgs: bool,
273}
274
275impl Default for WindowModalOpts {
276	fn default() -> Self {
277		Self {
278			class_name: "".to_owned(),
279			class_style: co::CS::DBLCLKS,
280			class_icon: Icon::None,
281			class_cursor: Cursor::Idc(co::IDC::ARROW),
282			class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
283			title: "".to_owned(),
284			size: dpi(500, 400),
285			style: co::WS::CAPTION
286				| co::WS::SYSMENU
287				| co::WS::CLIPCHILDREN
288				| co::WS::BORDER
289				| co::WS::VISIBLE,
290			ex_style: co::WS_EX::LEFT | co::WS_EX::DLGMODALFRAME,
291			process_dlg_msgs: true,
292		}
293	}
294}
295
296/// Options to create a [`WindowModeless`](crate::gui::WindowModeless)
297/// programmatically with
298/// [`WindowModeless::new`](crate::gui::WindowModeless::new).
299pub struct WindowModelessOpts {
300	/// Window class name to be
301	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
302	///
303	/// Defaults to an auto-generated string.
304	pub class_name: String,
305	/// Window class styles to be
306	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
307	///
308	/// Defaults to `co::CS::DBLCLKS`.
309	pub class_style: co::CS,
310	/// Window main icon to be
311	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
312	///
313	/// Defaults to `gui::Icon::None`.
314	pub class_icon: Icon,
315	/// Window cursor to be
316	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
317	///
318	/// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
319	pub class_cursor: Cursor,
320	/// Window background brush to be
321	/// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
322	///
323	/// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
324	pub class_bg_brush: Brush,
325
326	/// Window title to be
327	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
328	///
329	/// Defaults to empty string.
330	pub title: String,
331	/// Left and top position coordinates of control within parent's client
332	/// area, to be
333	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
334	///
335	/// Defaults to `gui::dpi(0, 0)`.
336	pub position: (i32, i32),
337	/// Width and height of window client area, in pixels, to be
338	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
339	/// Does not include title bar or borders.
340	///
341	/// Defaults to `gui::dpi(220, 150)`.
342	pub size: (i32, i32),
343	/// Window styles to be
344	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
345	///
346	/// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
347	///
348	/// Suggestions:
349	/// * `WS::SIZEBOX` to make the window resizable.
350	pub style: co::WS,
351	/// Extended window styles to be
352	/// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
353	///
354	/// Defaults to `WS_EX::LEFT | WS_EX::TOOLWINDOW`.
355	pub ex_style: co::WS_EX,
356}
357
358impl Default for WindowModelessOpts {
359	fn default() -> Self {
360		Self {
361			class_name: "".to_owned(),
362			class_style: co::CS::DBLCLKS,
363			class_icon: Icon::None,
364			class_cursor: Cursor::Idc(co::IDC::ARROW),
365			class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
366			title: "".to_owned(),
367			position: dpi(0, 0),
368			size: dpi(220, 150),
369			style: co::WS::CAPTION
370				| co::WS::SYSMENU
371				| co::WS::CLIPCHILDREN
372				| co::WS::BORDER
373				| co::WS::VISIBLE,
374			ex_style: co::WS_EX::LEFT | co::WS_EX::TOOLWINDOW,
375		}
376	}
377}
378
379/// The class background brush to be loaded for
380/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
381/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
382/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
383pub enum Brush {
384	/// A solid [system color](co::COLOR).
385	Color(co::COLOR),
386	/// A brush handle, previously created by you.
387	Handle(HBRUSH),
388	/// No brush.
389	None,
390}
391
392impl Brush {
393	/// Converts the contents of `Brush` to `HBRUSH`.
394	#[must_use]
395	pub fn as_hbrush(&self) -> HBRUSH {
396		match self {
397			Brush::Color(c) => HBRUSH::from_sys_color(*c),
398			Brush::Handle(h) => unsafe { h.raw_copy() },
399			Brush::None => HBRUSH::NULL,
400		}
401	}
402}
403
404/// The class cursor to be loaded for
405/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
406/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
407/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
408pub enum Cursor {
409	/// A cursor handle, previously loaded by you.
410	Handle(HCURSOR),
411	/// A resource ID.
412	Id(u16),
413	/// A [`co::IDC`](crate::co::IDC) constant for a stock system cursor.
414	Idc(co::IDC),
415	/// No cursor.
416	None,
417	/// A resource string identifier.
418	Str(WString),
419}
420
421impl Cursor {
422	/// Converts the contents of `Cursor` to `HCURSOR`.
423	#[must_use]
424	pub fn as_hcursor(&self, hinst: &HINSTANCE) -> SysResult<HCURSOR> {
425		unsafe {
426			Ok(match self {
427				Cursor::Handle(h) => h.raw_copy(),
428				Cursor::Id(id) => hinst.LoadCursor(IdIdcStr::Id(*id))?.leak(),
429				Cursor::Idc(idc) => HINSTANCE::NULL.LoadCursor(IdIdcStr::Idc(*idc))?.leak(),
430				Cursor::None => HCURSOR::NULL,
431				Cursor::Str(s) => hinst.LoadCursor(IdIdcStr::Str(s.clone()))?.leak(),
432			})
433		}
434	}
435}
436
437/// The class icon to be loaded for
438/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
439/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
440/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
441pub enum Icon {
442	/// An icon handle, previously loaded by you.
443	Handle(HICON),
444	/// A resource ID.
445	Id(u16),
446	/// A [`co::IDC`](crate::co::IDC) constant for a stock system icon.
447	Idi(co::IDI),
448	/// No icon.
449	None,
450	/// A resource string identifier.
451	Str(WString),
452}
453
454impl Icon {
455	/// Converts the contents of `Icon` to `HICON`.
456	#[must_use]
457	pub fn as_hicon(&self, hinst: &HINSTANCE) -> SysResult<HICON> {
458		unsafe {
459			Ok(match self {
460				Icon::Handle(h) => h.raw_copy(),
461				Icon::Id(id) => hinst.LoadIcon(IdIdiStr::Id(*id))?.leak(),
462				Icon::Idi(idi) => HINSTANCE::NULL.LoadIcon(IdIdiStr::Idi(*idi))?.leak(),
463				Icon::None => HICON::NULL,
464				Icon::Str(s) => hinst.LoadIcon(IdIdiStr::Str(s.clone()))?.leak(),
465			})
466		}
467	}
468}